﻿using HCMS.Const;
using HCMS.Extensions;
using HCMS.IServices.Manage;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using System.Security.Claims;

namespace HCMS.Web.Manage.ServicesExtensions
{
    /// <summary>
    /// 自定义 Cookie 身份验证方法
    /// </summary>
    /// <remarks>
    /// 为了保证登录 Cookie 可以响应后端更改，增加此处理。
    /// 每次请求都会取出 Cookie 信息，跟后端验证。如果后端已经显示账户失效，则系统直接退出登录
    /// </remarks>
    public class CustomCookieAuthenticationEvents : CookieAuthenticationEvents
    {
        private readonly IAdminAppService adminAppService;

        public CustomCookieAuthenticationEvents(IAdminAppService adminAppService)
        {
            this.adminAppService = adminAppService;
        }

        public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
        {
            // 跟 Redis 存储的登录信息比较
            if (context.Principal != null && context.Principal.Claims != null)
            {
                Claim? claimId = context.Principal.Claims.FirstOrDefault(t => t.Type == ManageConst_ClaimTypes.Id);
                if (claimId != null && !string.IsNullOrWhiteSpace(claimId.Value))
                {
                    Claim? claimTs = context.Principal.Claims.FirstOrDefault(t => t.Type == ManageConst_ClaimTypes.ts);
                    // 从 Redis 获取已登录信息
                    string ts = await adminAppService.GetLoginedInfo(claimId.Value.ToInt(0));
                    // 时间戳一致，验证通过
                    if (ts == claimTs?.Value)
                    {
                        return;
                    }
                }
            }

            // 验证失败
            context.RejectPrincipal();
            await context.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        }
    }
}
